package com.xnyzc.lhy.order.service.impl.order;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyzc.lhy.common.component.amap.GouldMapUtils;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.MessageConstant;
import com.xnyzc.lhy.common.constant.MqConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.*;
import com.xnyzc.lhy.common.entity.netty.NettyDriverOrderInfo;
import com.xnyzc.lhy.common.exception.DiDiException;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EDiDiErrorCode;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.gould.EGould;
import com.xnyzc.lhy.common.penum.order.*;
import com.xnyzc.lhy.common.penum.vehicle.ECallVehType;
import com.xnyzc.lhy.common.penum.vehicle.EvehicleType;
import com.xnyzc.lhy.common.util.*;
import com.xnyzc.lhy.order.common.constants.BillConstant;
import com.xnyzc.lhy.order.common.constants.OrderStatusConstant;
import com.xnyzc.lhy.order.entity.bill.OaDBill;
import com.xnyzc.lhy.order.entity.common.bill.BillRulesCommon;
import com.xnyzc.lhy.order.entity.common.gps.GpsCommon;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.gps.OaDVehicleGps;
import com.xnyzc.lhy.order.entity.mq.OaCOrderPersonal;
import com.xnyzc.lhy.order.entity.order.DriverCancelOrderRecord;
import com.xnyzc.lhy.order.entity.order.OaCOrder;
import com.xnyzc.lhy.order.entity.order.OaDOrder;
import com.xnyzc.lhy.order.entity.order.OaOrderOtherPrice;
import com.xnyzc.lhy.order.entity.param.order.*;
import com.xnyzc.lhy.order.entity.param.synchronization.StatusCallbackParam;
import com.xnyzc.lhy.order.entity.result.order.OrderBillDetailResults;
import com.xnyzc.lhy.order.entity.result.order.StartRouteMessage;
import com.xnyzc.lhy.order.entity.result.order.StartRouteOrderMessage;
import com.xnyzc.lhy.order.entity.system.OaSysBillRules;
import com.xnyzc.lhy.order.entity.system.OaSysGlobalConfig;
import com.xnyzc.lhy.order.entity.user.OaDUser;
import com.xnyzc.lhy.order.entity.user.OaDUserInfo;
import com.xnyzc.lhy.order.entity.user.message.OaSysMessage;
import com.xnyzc.lhy.order.entity.util.OrderUtil;
import com.xnyzc.lhy.order.entity.wallet.OaDFreeze;
import com.xnyzc.lhy.order.feign.amap.IAmapService;
import com.xnyzc.lhy.order.feign.didi.IDidiService;
import com.xnyzc.lhy.order.feign.finance.IOaDFreezeService;
import com.xnyzc.lhy.order.feign.push.FeignMessageSendService;
import com.xnyzc.lhy.order.feign.statistics.FeignTrajectoryService;
import com.xnyzc.lhy.order.mapper.order.*;
import com.xnyzc.lhy.order.mapper.system.OaSysGlobalConfigMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserInfoMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserMapper;
import com.xnyzc.lhy.order.mq.MqOrderProducer;
import com.xnyzc.lhy.order.service.driver.IOaDUserInfoService;
import com.xnyzc.lhy.order.service.order.IOaCOrderPersonalDiDiService;
import com.xnyzc.lhy.order.service.order.IOaDOrderCorrelationService;
import com.xnyzc.lhy.order.service.order.IOaDOrderService;
import com.xnyzc.lhy.order.service.user.message.IOaSysMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.xnyzc.lhy.common.entity.ParameterEnum.ONE;
import static com.xnyzc.lhy.common.entity.ParameterEnum.ZERO;


/**
 * <p>
 * 司机接单表 服务实现类
 * </p>
 *
 * @author huxuekuo
 * @since 2019-07-19
 */
@Service
@Slf4j
public class OaDOrderServiceImpl extends ServiceImpl<OaDOrderMapper, OaDOrder> implements IOaDOrderService {

    private final Integer GET_IMAGE_FILED = 111;

    /**
     * 控制行程录音开关
     * 0 -- 关闭  1 -- 开始
     */
    @Value("${global.startRecord}")
    private Integer startRecord;
    /**
     * 司机订单Mapper
     */
    @Autowired
    private OaDOrderMapper orderMapper;
    @Autowired
    private IOaDOrderService oaDOrderService;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private OaDUserMapper oaDUserMapper;
    /**
     * 订单私有方法
     */
    @Autowired
    private OrderCommon common;


    @Autowired
    private MqOrderProducer producer;

    /**
     * 计费规则封装类
     */
    @Autowired
    private BillRulesCommon billRulesCommon;

    /**
     * redis私有方法
     */
    @Autowired
    private RedisCommon redisCommon;

    /**
     * 定位私用类
     */
    @Autowired
    private GpsCommon gpsCommon;

    /**
     * 其他费用Mapper
     */
    @Autowired
    private OaOrderOtherPriceMapper otherPriceMapper;

    @Autowired
    private IAmapService amapService;

    @Autowired
    private OaCOrderPersonalDiDiMapper personalDiDiMapper;
    @Autowired
    private IOaCOrderPersonalDiDiService personalDiDiService;
    @Autowired
    private IOaDUserInfoService dUserInfoService;

    @Autowired
    private IOaDFreezeService oaDFreezeService;

    @Autowired
    OaDUserInfoMapper oaDUserInfoMapper;
    @Autowired
    private IOaDOrderCorrelationService iOaDOrderCorrelationService;

    @Autowired
    private IAmapService iAmapService;
    @Autowired
    private OaSysGlobalConfigMapper oaSysGlobalConfigMapper;
    /**
     * 图片服务
     */
    @Autowired
    private FeignMessageSendService feignMessageSendService;
    @Autowired
    private OaOrderOtherPriceMapper oaOrderOtherPriceMapper;

    @Autowired
    private IOaSysMessageService iOaSysMessageService;

    @Autowired
    private OaDOrderCorrelationServiceImpl oaDOrderCorrelationServiceImpl;

    @Autowired
    private IDidiService iDidiService;

    @Autowired
    private DriverCancelOrderRecordMapper driverCancelOrderRecordMapper;
    @Autowired
    FeignTrajectoryService feignTrajectoryService;
    @Autowired
    private OaSysOrderDetailsMapper oaSysOrderDetailsMapper;
    public static String serviceId;

    @Value("${global.amap.lyServiceId}")
    public void setServiceId(String amapServiceId) {
        serviceId = amapServiceId;
    }

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 司机订单生成
     *
     * @param oaDOrder 司机接单表
     * @return
     */
    @Override
    public Boolean addDriverOrderInfo(OaDOrder oaDOrder) {
        if (CheckUtil.objIsEmpty(oaDOrder)) {
            throw DiDiException.create(EDiDiErrorCode.parameterError);
        }
        boolean save = true;
        try {
            save = oaDOrderService.save(oaDOrder);
        } catch (Exception e) {
            log.error("司机接单表插入异常，异常信息：{}", e.getMessage());
        }
        return save;
    }

    /**
     * 滴滴取消订单
     *
     * @param orderDetailParam
     * @return
     */
    @Override
    public void updateOrderPersonalStatus(OrderDetailParam orderDetailParam) {
        // 处理业务逻辑
        producer.sendMsg(orderDetailParam, MqConstant.DIDI_CANCEL_ORDER);
    }

    /**
     * 抢单失败，修改状态
     *
     * @param orderNo
     * @return
     */
    @Override
    public Boolean singleFailureStatus(String orderNo) {
        if (CheckUtil.strIsEmpty(orderNo)) {
            log.info("抢单失败，修改状态，我带来的参数为空");
            throw DiDiException.create(EDiDiErrorCode.parameterError);
        }
        log.info("抢单失败，修改状态，我带来的参数是：{}", orderNo);
        // 查询version
        QueryWrapper<OaCOrderPersonal> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
        queryWrapper.select(OaCOrderPersonal.VERSION, OaCOrderPersonal.DRIVER_ID, OaCOrderPersonal.ORDER_STATUS);
        OaCOrderPersonal personal;
        try {
            personal = personalDiDiMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw DiDiException.create(EDiDiErrorCode.cancelOrderFail);
        }
        // 修改
        UpdateWrapper<OaCOrderPersonal> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(OaCOrderPersonal.DIDI_ORDER_STATUS, EDiDiOrderStatus.otherPlatformsAccept.getDidiType());
        updateWrapper.set(OaCOrderPersonal.ORDER_STATUS, EDiDiOrderStatus.otherPlatformsAccept.getType());
        updateWrapper.set(OaCOrderPersonal.UPDATE_TIME, new Date());
        if (personal.getVersion() != null) {
            updateWrapper.set(OaCOrderPersonal.VERSION, personal.getVersion() + 1);
            updateWrapper.eq(OaCOrderPersonal.VERSION, personal.getVersion());
        }
        updateWrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
        boolean update;
        try {
            update = personalDiDiService.update(updateWrapper);
        } catch (Exception e) {
            log.info(e.getMessage());
            throw DiDiException.create(EDiDiErrorCode.mySqlOperationFail);
        }
        log.info("数据库状态修改成功，将要释放司机，释放的司机ID为：{}", personal.getDriverId());
        // 解除司机锁定，并且订单状态为0，1，17才可以释放司机，且司机当前订单为此单。
        if (CheckUtil.objIsNotEmpty(personal.getDriverId())) {
            QueryWrapper<OaDUserInfo> dUserWrapper = new QueryWrapper<>();
            dUserWrapper.select(OaDUserInfo.CURRENT_ORDER_NO);
            dUserWrapper.eq(OaDUserInfo.DRIVER_ID, personal.getDriverId());
            OaDUserInfo one = dUserInfoService.getOne(dUserWrapper);
            if (StringUtils.equals(one.getCurrentOrderNo(), orderNo)) {
                if (StringUtils.equals(personal.getOrderStatus().toString(), "0")
                        || StringUtils.equals(personal.getOrderStatus().toString(), "1")
                        || StringUtils.equals(personal.getOrderStatus().toString(), "17")) {
                    try {
                        log.info("DRIVER_HISTORY 司机被释放了,司机当前订单号:[{}],当前订单状态:[{}],司机ID:[{}]",
                                orderNo,
                                personal.getOrderStatus().toString(),
                                personal.getDriverId().toString()
                        );
                        driverUnlock(personal.getDriverId().toString());
                    } catch (Exception e) {
                        log.info("我抛出异常了，异常信息为：{}，释放司机运力失败！！", e.getMessage());
                    }
                }
            }
        }
        return update;
    }

    /**
     * 解除司机锁定
     *
     * @param driverId
     * @return
     */
    @Override
    public Boolean driverUnlock(String driverId) {
        log.info("开始释放司机，司机ID为：{}", driverId);
        UpdateWrapper<OaDUserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(OaDUserInfo.IS_ORDER, 0);
        updateWrapper.set(OaDUserInfo.CURRENT_ORDER_NO, "");
        updateWrapper.eq(OaDUserInfo.DRIVER_ID, driverId);
        try {
            return dUserInfoService.update(updateWrapper);
        } catch (Exception e) {
            log.error("解除司机锁定失败，{}", e.getMessage());
        }
        return false;
    }

    /**
     * 获取司机手机号
     *
     * @param driverId 司机ID
     * @return
     */
    @Override
    public String getDriverPhone(String driverId) {
        try {
            return oaDUserMapper.getDriverPhone(driverId);
        } catch (Exception e) {
            log.error("获取司机手机号失败！报错信息为{}", e.getMessage());
        }
        return null;
    }

    /**
     * 查看订单详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public OaCOrderPersonal billDetails(String orderNo) {
//        String str = redisCommon.getStr(RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo);
        OaCOrderPersonal oaCOrderPersonal = null;
//        if (CheckUtil.strIsNotEmpty(str)) {
//            oaCOrderPersonal = JSON.parseObject(str, OaCOrderPersonal.class);
//        } else {
        QueryWrapper<OaCOrderPersonal> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
        try {
            oaCOrderPersonal = personalDiDiMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            throw DiDiException.create(EDiDiErrorCode.orderPersonalSelectFail);
        }
//        }
        if (CheckUtil.objIsEmpty(oaCOrderPersonal)) {
            throw DiDiException.create(EDiDiErrorCode.orderPersonalSelectFail);
        }
        return oaCOrderPersonal;
    }

    /**
     * 根据车辆信息与人员订单信息添加订单信息
     *
     * @param nearCar 车辆实时轨迹信息
     * @param order   订单信息
     * @return
     */
    @Override
    public boolean addOrder(OaDVehicleGps nearCar, OrderParam order) {
        //生成订单
        //设置更改时间与创建时间
        Date date = new Date();
        order.setCreateTime(date);
        order.setUpdateTime(date);
        order.setStriveTime(date);
        order.setVehicleId(nearCar.getVehId());
        order.setOrderStatus(EOrderStatus.driverOrder.getType());
        orderMapper.insert(order);
        return true;
    }


    /**
     * 前往预约地点
     * <p>
     * 有预约用流水号查询人员订单中的流水
     * 没有预约用订单号查询人员订单
     *
     * @param dUserId 司机用户ID
     * @param orderNo 订单号
     * @return
     */
    @Override
    public Rv startRoute(String dUserId, String orderNo) {
        OaCOrder oaCOrder = common.queryOrderMessage(orderNo);
        //查询订单
        OaDOrder oaDOrder = orderMapper.selectById(orderNo);
        Date startDate = new Date();
        if (CheckUtil.objIsEmpty(oaDOrder) || CheckUtil.objIsEmpty(oaCOrder)) {
            throw PangException.create(EErrorCode.noData);
        }
        //验证当前订单状态是否可以继续
        common.canTheOrderContinue(oaCOrder.getOrderStatus());
        //更新司机订单
        oaDOrder.setDepartureTime(startDate);
        oaDOrder.setOrderStatus(EOrderStatus.reservationLocation.getType());
        oaCOrder.setOrderStatus(EOrderStatus.reservationLocation.getType());
        if (!this.updateById(oaDOrder) || !common.updateOrder(oaCOrder)) {
            throw PangException.create(EErrorCode.unkown);
        }
        redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrder.getOrderNo(), JSON.toJSONString(oaCOrder));
        /**
         * 封装返回参数.....
         */
        StartRouteOrderMessage orderMessage = new StartRouteOrderMessage();
        List<StartRouteMessage> ResultList = new ArrayList<>();
        StartRouteMessage startRouteMessage = new StartRouteMessage();
        startRouteMessage.setPhone(oaCOrder.getPassengerPhone());
        startRouteMessage.setEndLat(oaCOrder.getEndLat());
        startRouteMessage.setStartLat(oaCOrder.getStartLat());
        startRouteMessage.setStartLng(oaCOrder.getStartLng());
        startRouteMessage.setEndLng(oaCOrder.getEndLng());
        startRouteMessage.setOrderStatus(oaCOrder.getOrderStatus());
        startRouteMessage.setVehOrderStatusInt(oaCOrder.getOrderStatus());
        orderMessage.setStartPoint(oaCOrder.getStartAddress());
        orderMessage.setEndPoint(oaCOrder.getEndAddress());
        //设置距离用户公里数
        String vehJson = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + oaCOrder.getDriverId());
        OaDVehicleGps oaDVehicleGps = JSON.parseObject(vehJson, OaDVehicleGps.class);
        startRouteMessage.setDistance("0.5公里");
        startRouteMessage.setDuration("1分钟");
//      #####################因为没缓存，在这写死测一下
//        oaDVehicleGps = new OaDVehicleGps();
//        oaDVehicleGps.setDriverId(Long.valueOf(dUserId));
//        oaDVehicleGps.setVehId(1639270276726784L);
//        oaDVehicleGps.setLng("116.417428");
//        oaDVehicleGps.setLat("39.91923");
//        oaDVehicleGps.setVehType(0);
//        oaDVehicleGps.setIsTrue(0);
//      #####################因为没缓存，在这写死测一下

        //转换为km
        if (CheckUtil.objIsNotEmpty(oaDVehicleGps.getLng()) && CheckUtil.objIsNotEmpty(oaDVehicleGps.getLat())) {
            Map<String, String> distanceAndDuration = amapService.getDistanceAndDuration(oaDVehicleGps.getLng() + "," + oaDVehicleGps.getLat(), oaCOrder.getStartLng() + "," + oaCOrder.getStartLat());
            //设置距离用户公里数
            startRouteMessage.setDistance(distanceAndDuration.get(EGould.gouldDistance.getValue()));
            startRouteMessage.setDuration(distanceAndDuration.get(EGould.gouldDuration.getValue()));
        }
        String phone = oaCOrder.getPassengerPhone();
        //获取手机号
        String tailNumber = "";
        if (phone.length() > 5) {
            tailNumber = phone.substring(phone.length() - 4, phone.length());
        }
        startRouteMessage.setTailNumber(MessageConstant.TAILNUMBER + tailNumber);
        //现在去xxx接手机尾号xxxx的乘客
        orderMessage.setMsg(MessageConstant.VOICE_NOW_GO + oaCOrder.getStartAddress() + MessageConstant.VOICE_CONNECT + MessageConstant.VOICE_TAIL_NUMBER + NumberToChn.NumberToChn(tailNumber) + MessageConstant.VOICE_PASSENGER);
        orderMessage.setResrvationType(ECallVehType.finaByValue(oaCOrder.getOrderType()));
        ResultList.add(startRouteMessage);
        orderMessage.setNumber(ResultList.size());
        orderMessage.setStartRouteMessageList(ResultList);
        orderMessage.setOrderType(OrderUtil.orderType(oaDOrder.getIsCarpool()));
        orderMessage.setOrderNo(oaDOrder.getOrderNo());
        return Rv.wrap(EErrorCode.success, orderMessage);
    }

    /**
     * 更新订单详细信息
     *
     * @param oaSysOrderDetailsParam
     * @return
     */
    @Override
    public Rv updateOrderDetails(OaSysOrderDetailsParam oaSysOrderDetailsParam) {
        log.info("更新订单详细信息,请求参数:{}", JSON.toJSONString(oaSysOrderDetailsParam));
        if (CheckUtil.objIsEmpty(oaSysOrderDetailsParam.getRequestType()) ||
                CheckUtil.objIsEmpty(oaSysOrderDetailsParam.getOrderNo())) {
            return Rv.error(EErrorCode.missingArg);
        }
        //查看司机有无订单
        QueryWrapper<OaDOrder> oaDOrderQueryWrapper = new QueryWrapper<>();
        oaDOrderQueryWrapper.eq(OaDOrder.ORDER_NO, oaSysOrderDetailsParam.getOrderNo());
        OaDOrder oaDOrder = orderMapper.selectOne(oaDOrderQueryWrapper);
        if (null == oaDOrder) {
            return Rv.error(EErrorCode.unOrder);
        }
        QueryWrapper<OaSysOrderDetails> oaSysOrderDetailsQueryWrapper = new QueryWrapper<>();
        oaSysOrderDetailsQueryWrapper.eq(OaSysOrderDetails.ORDER_NO, oaSysOrderDetailsParam.getOrderNo());
        OaSysOrderDetails oaSysOrderDetails = oaSysOrderDetailsMapper.selectOne(oaSysOrderDetailsQueryWrapper);
        boolean isUpdate = true;
        if (null == oaSysOrderDetails) {
            isUpdate = false;
            //注意！需要初始化
            oaSysOrderDetails = new OaSysOrderDetails();
            oaSysOrderDetails.setDetailsId(IDUtil.nextId());
            //确保当获取null时,必须类型是1
            oaSysOrderDetailsParam.setRequestType(1);
        }
        if (oaSysOrderDetailsParam.getRequestType() == 1) {//保存去接乘客信息
            oaSysOrderDetails.setDriverId(oaSysOrderDetailsParam.getDriverId());
            oaSysOrderDetails.setDriverPhone(oaSysOrderDetailsParam.getDriverPhone());
            oaSysOrderDetails.setOrderNo(oaSysOrderDetailsParam.getOrderNo());
            oaSysOrderDetails.setOrderStatus(oaSysOrderDetailsParam.getOrderStatus());
            oaSysOrderDetails.setOrderType(oaSysOrderDetailsParam.getOrderType());
            oaSysOrderDetails.setVehicleNo(oaSysOrderDetailsParam.getVehicleNo());
            oaSysOrderDetails.setMeetCTime(new Date());
            oaSysOrderDetails.setMeetCStartName(oaSysOrderDetailsParam.getMeetCStartName());
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getMeetCStartLat())) {
                oaSysOrderDetails.setMeetCStartLat(oaSysOrderDetailsParam.getMeetCStartLat());
            }
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getMeetCStartLng())) {
                oaSysOrderDetails.setMeetCStartLng(oaSysOrderDetailsParam.getMeetCStartLng());
            }
            //做了一个兼容处理
            if (isUpdate) {
                oaSysOrderDetailsMapper.updateById(oaSysOrderDetails);
            } else {
                oaSysOrderDetailsMapper.insert(oaSysOrderDetails);
            }
        } else if (oaSysOrderDetailsParam.getRequestType() == 2
                && CheckUtil.objIsNotEmpty(oaSysOrderDetails.getDetailsId())) {//保存司机已就位信息
            oaSysOrderDetails.setDriverInPlaceTime(new Date());
            oaSysOrderDetails.setDriverInPlaceStartName(oaSysOrderDetailsParam.getDriverInPlaceStartName());
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getDriverInPlaceStartLat())) {
                oaSysOrderDetails.setDriverInPlaceStartLat(oaSysOrderDetailsParam.getDriverInPlaceStartLat());
            }
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getDriverInPlaceStartLng())) {
                oaSysOrderDetails.setDriverInPlaceStartLng(oaSysOrderDetailsParam.getDriverInPlaceStartLng());
            }
            oaSysOrderDetailsMapper.updateById(oaSysOrderDetails);
        } else if (oaSysOrderDetailsParam.getRequestType() == 3
                && CheckUtil.objIsNotEmpty(oaSysOrderDetails.getDetailsId())) {//保存开始行程信息
            oaSysOrderDetails.setStartJourneyName(oaSysOrderDetailsParam.getStartJourneyName());
            oaSysOrderDetails.setStartJourneyTime(new Date());
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getStartJourneyLat())) {
                oaSysOrderDetails.setStartJourneyLat(oaSysOrderDetailsParam.getStartJourneyLat());
            }
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getStartJourneyLng())) {
                oaSysOrderDetails.setStartJourneyLng(oaSysOrderDetailsParam.getStartJourneyLng());
            }
            oaSysOrderDetailsMapper.updateById(oaSysOrderDetails);
        } else if (oaSysOrderDetailsParam.getRequestType() == 4
                && CheckUtil.objIsNotEmpty(oaSysOrderDetails.getDetailsId())) {//保存结束行程信息
            oaSysOrderDetails.setEndJourneyName(oaSysOrderDetailsParam.getEndJourneyName());
            oaSysOrderDetails.setEndJourneyTime(new Date());
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getEndJourneyLat())) {
                oaSysOrderDetails.setEndJourneyLat(oaSysOrderDetailsParam.getEndJourneyLat());
            }
            if (CheckUtil.objIsNotEmpty(oaSysOrderDetailsParam.getEndJourneyLng())) {
                oaSysOrderDetails.setEndJourneyLng(oaSysOrderDetailsParam.getEndJourneyLng());
            }
            oaSysOrderDetailsMapper.updateById(oaSysOrderDetails);
            //上传点位数据
            iAmapService.uploadTrackFromMongo(oaDOrder);
        } else {
            return Rv.error(EErrorCode.missingArg);
        }
        return Rv.wrap();
    }

    /**
     * 确认上车
     * 1.根据车辆订单号查询人员订单号,更改确认时间
     *
     * @param orderNo 根据车辆
     * @return
     */
    @Override
    public Rv notarizeGetOn(NotarizeGetOnOrder orderNo) {
        log.info("ORDER_HISTORY 订单号:[{}],调用了确认上车接口,请求参数:[{}]", orderNo.getOrderNo(), orderNo);
        try {
            //oaDOrder查询出订单号
            OaDOrder oaDOrder = orderMapper.selectById(orderNo.getOrderNo());
            com.xnyzc.lhy.order.entity.order.OaCOrderPersonal oaCOrderPersonal = oaCOrderPersonalMapper.selectOne(Qw.create().eq(OaCOrderPersonal.ORDER_NO, orderNo.getOrderNo()));
            if (!CheckUtil.objIsEmpty(oaDOrder) && !CheckUtil.objIsEmpty(oaCOrderPersonal)) {
                OaCOrder oaCOrder = common.queryOrderMessage(orderNo.getOrderNo());
                if (CheckUtil.objIsEmpty(oaCOrder)) {
                    log.info("ORDER_HISTORY 订单号:[{}],未获取到订单信息,请求参数:[{}]", orderNo.getOrderNo(), orderNo);
                    return Rv.wrap(EErrorCode.noData);
                }
                //验证当前订单状态是否可以继续
                common.canTheOrderContinue(oaCOrder.getOrderStatus());
                Date date = new Date();
                //设置订单状态:行程中
                oaCOrder.setOrderStatus(EOrderStatus.duringTrip.getType());
                oaCOrder.setDidiOrderStatus(EDiDiOrderStatus.duringTrip.getDidiType());
                //开始送客开始计价
                oaDOrder.setBeginChargeTime(date);
                oaDOrder.setActualStartName(orderNo.getActualStartName());
                oaDOrder.setActualFlat(orderNo.getActualFlat());
                oaDOrder.setActualFlng(orderNo.getActualFlng());
                oaDOrder.setOrderStatus(EOrderStatus.duringTrip.getType());
                oaCOrder.setNotarizeTime(date);
                oaCOrder.setOrderTime(date);
                //设置乘客端订单信息和更新
                oaCOrderPersonal.setOrderStatus(EOrderStatus.duringTrip.getType());
                oaCOrderPersonal.setDidiOrderStatus(EDiDiOrderStatus.duringTrip.getDidiType());
                oaCOrderPersonal.setNotarizeTime(date);
                oaCOrderPersonalMapper.updateById(oaCOrderPersonal);
                //更改个人用户订单状态以及车辆订单开始计价
                if (common.updateOrder(oaCOrder) && this.updateById(oaDOrder)) {
                    redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrder.getOrderNo(), JSON.toJSONString(oaCOrder));
                    //获取距离目的地距离和时间
                    HashMap<String, String> distanceAndDuration = amapService.getDistanceAndDuration(oaCOrder.getStartLng() + "," + oaCOrder.getStartLat(), oaCOrder.getEndLng() + "," + oaCOrder.getEndLat());
                    //获取手机号 && 手机尾号
                    String phone = oaCOrder.getPassengerPhone();
                    String tailNumber = oaCOrder.getPassengerPhoneSuffix();
                    // 司机状态同步
                    StatusCallbackParam statusCallbackParam = new StatusCallbackParam();
                    statusCallbackParam.setChannel(oaCOrderPersonal.getOrderChannel());
                    statusCallbackParam.setOpen_oid(oaCOrder.getDidiOrderId());
                    statusCallbackParam.setOrder_id(oaCOrder.getOrderNo());
                    statusCallbackParam.setDriver_id(oaCOrder.getDriverId().toString());
                    statusCallbackParam.setStatus(oaCOrder.getOrderStatus());
                    statusCallbackParam.setChannel(oaCOrder.getOrderChannel());
                    String str = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + oaCOrder.getDriverId());
                    if (CheckUtil.strIsNotEmpty(str)) {
                        OaDVehicleGps oaDVehicleGps = JSON.parseObject(str, OaDVehicleGps.class);
                        statusCallbackParam.setDriver_lng(new BigDecimal(oaDVehicleGps.getLng()));
                        statusCallbackParam.setDriver_lat(new BigDecimal(oaDVehicleGps.getLat()));
                    }
                    statusCallbackParam.setIsRetry(false);

                    // 同步调用滴滴同步状态,如果失败,异步重试
                    Rv rv = iDidiService.statusCallback(statusCallbackParam);
                    if (rv.getCode() != EErrorCode.success.getValue()) {
                        log.info("ORDER_HISTORY 订单号:[{}],确认上车接口,调用滴滴服务返回失败,进入重试机制,请求参数:[{}],调用滴滴服务返回值:[{}] ", orderNo, statusCallbackParam, rv);
                        producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC);
                    }
                    log.info("ORDER_HISTORY 订单号:[{}],确认上车接口,调用滴滴状态同步 参数:[{}],返回值:[{}]", orderNo.getOrderNo(), statusCallbackParam, rv);
                    Qd result = Qd.create()
                            .add("startAddress", oaCOrder.getStartAddress())
                            .add("phone", phone)
                            .add("tid", common.getTid(String.valueOf(TokenUtil.getTokenUserId())))
                            .add("serviceId", common.getServiceId())
                            .add("gpsId", oaCOrder.getGpsId())
                            .add("tailNumber", MessageConstant.TAILNUMBER + tailNumber)
                            .add("distance", distanceAndDuration.get(EGould.gouldDistance.getValue()))
                            .add("duration", distanceAndDuration.get(EGould.gouldDuration.getValue()))
                            .add("endAddress", oaCOrder.getEndAddress())
                            .add("orderStatus", oaCOrder.getOrderStatus())
                            .add("msg", MessageConstant.VOICE_HAS + MessageConstant.VOICE_CONNECT + MessageConstant.VOICE_TO + MessageConstant.VOICE_TAIL_NUMBER + NumberToChn.NumberToChn(tailNumber) + MessageConstant.VOICE_PROMPT)
                            .add("vehType", EvehicleType.findById(oaCOrder.getVehicleType()).getValue())
                            .add("orderType", OrderUtil.resrvationType(oaDOrder.getAppointmentTime()));
                    log.info("ORDER_HISTORY 订单号:[{}],确认上车接口,返回参数:[{}],调用司机状态到滴滴请求参数:[{}],调用滴滴服务返回值:[{}] ", orderNo.getOrderNo(), result, statusCallbackParam, rv);
                    result.add("orderNo", orderNo.getOrderNo());
                    return Rv.wrap(EErrorCode.success, result);
                } else {
                    log.info("ORDER_HISTORY 订单号:[{}],确认上车接口,更改用户订单失败 OR 更改司机订单失败", orderNo.getOrderNo());
                    throw PangException.create(EErrorCode.unkown);
                }
            } else {
                log.info("ORDER_HISTORY 订单号:[{}],确认上车接口,未查询到司机订单", orderNo.getOrderNo());
                throw PangException.create(EErrorCode.noData);
            }
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.info("ORDER_HISTORY 订单号:[{}],确认上车接口, 错误行数:[{}],错误信息:[{}]", orderNo.getOrderNo(), stackTraceElement.getLineNumber(), e);
            throw PangException.create(EErrorCode.sysError);
        }
    }


    /**
     * 到达预约地点
     *
     * @return
     */
    @Override
    public Rv arriveReservation(NotarizeGetOnOrder notarizeGetOnOrder) {
        String orderNo = notarizeGetOnOrder.getOrderNo();
        log.info("ORDER_HISTORY 订单号:[{}],调用了到达预约地点接口,请求参数:[{}]", orderNo, notarizeGetOnOrder);
        OaDOrder oaDOrder = orderMapper.selectById(orderNo);
        if (!CheckUtil.objIsEmpty(oaDOrder)) {
            OaCOrder oaCOrder = common.queryOrderMessage(orderNo);
            if (!CheckUtil.objIsEmpty(oaCOrder)) {
                List<OaSysGlobalConfig> oaSysGlobalConfigs = oaSysGlobalConfigMapper.selectList(null);
                OaSysGlobalConfig oaSysGlobalConfig = oaSysGlobalConfigs.get(0);
                if (CheckUtil.objIsNotEmpty(oaSysGlobalConfig.getArriveSiteMeter()) && oaSysGlobalConfig.getArriveSiteMeter() > 0) {
                    if (CheckUtil.objIsNotEmpty(notarizeGetOnOrder.getActualFlng()) && !notarizeGetOnOrder.getActualFlng().equals("0.0") &&
                            CheckUtil.objIsNotEmpty(notarizeGetOnOrder.getActualFlat()) && !notarizeGetOnOrder.getActualFlat().equals("0.0")) {
                        Integer distance = iAmapService.getLineDistance(notarizeGetOnOrder.getActualFlng(), notarizeGetOnOrder.getActualFlat(), oaCOrder.getStartLng(), oaCOrder.getStartLat());
                        if (distance > oaSysGlobalConfig.getArriveSiteMeter()) {
                            log.info("ORDER_HISTORY 订单号:[{}], 距离预约地点不在[{}]米范围内, 当前司机经纬度:[{},{}], 当前订单起点经纬度:[{},{}]", orderNo,
                                    oaSysGlobalConfig.getArriveSiteMeter(), notarizeGetOnOrder.getActualFlng(), notarizeGetOnOrder.getActualFlat()
                                    , oaCOrder.getStartLng(), oaCOrder.getStartLat());
                            throw PangException.create(EErrorCode.arriveReservationErr);
                        }
                    }
                }
                if (CheckUtil.objIsNotEmpty(notarizeGetOnOrder.getActualFlng()) && !notarizeGetOnOrder.getActualFlng().equals("0.0") &&
                        CheckUtil.objIsNotEmpty(notarizeGetOnOrder.getActualFlat()) && !notarizeGetOnOrder.getActualFlat().equals("0.0")) {
                    oaDOrder.setArriveReservationFlat(notarizeGetOnOrder.getActualFlat());
                    oaDOrder.setArriveReservationFlng(notarizeGetOnOrder.getActualFlng());
                }
                //验证当前订单状态是否可以继续
                common.canTheOrderContinue(oaCOrder.getOrderStatus());
                //更新订单状态
                oaCOrder.setOrderStatus(EOrderStatus.driverArrived.getType());
                oaDOrder.setOrderStatus(EOrderStatus.driverArrived.getType());
                oaCOrder.setDidiOrderStatus(EDiDiOrderStatus.driverArrived.getDidiType());
                oaCOrder.setArriveMeetPassengerTime(new Date());
                //更新乘客端的订单号状态
                com.xnyzc.lhy.order.entity.order.OaCOrderPersonal oaCOrderPersonal = oaCOrderPersonalMapper.selectOne(Qw.create().eq(OaCOrderPersonal.ORDER_NO, orderNo));
                if (CheckUtil.objIsNotEmpty(oaCOrderPersonal)) {
                    oaCOrderPersonal.setOrderStatus(EOrderStatus.driverArrived.getType());
                    oaCOrderPersonalMapper.updateById(oaCOrderPersonal);
                }
                if (!common.updateOrder(oaCOrder) || !this.updateById(oaDOrder)) {
                    log.info("ORDER_HISTORY 订单号:[{}], 更改订单信息失败", orderNo);
                    throw PangException.create(EErrorCode.unkown);
                }
                redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrder.getOrderNo(), JSON.toJSONString(oaCOrder));
                //获取手机尾号
                String phone = oaCOrder.getPassengerPhone();
                String phoneTailNumber = oaCOrder.getPassengerPhoneSuffix();
                Qd result = Qd.create()
                        .add("duration", oaCOrder.getDurationTime())
                        .add("distance", oaCOrder.getMilageDistance())
                        .add("startAddress", oaCOrder.getStartAddress())
                        .add("endAddress", oaCOrder.getEndAddress())
                        .add("phone", phone)
                        .add("msg", MessageConstant.VOICE_ARRIVE_RESERVATION_BEFORE + MessageConstant.VOICE_PLEASE_WAIT + MessageConstant.VOICE_BOARDING)
                        .add("orderStatus", oaCOrder.getOrderStatus())
                        .add("tailNumber", MessageConstant.TAILNUMBER + phoneTailNumber);

                // 司机状态同步
                StatusCallbackParam statusCallbackParam = new StatusCallbackParam();
                statusCallbackParam.setOpen_oid(oaCOrder.getDidiOrderId());
                statusCallbackParam.setOrder_id(oaCOrder.getOrderNo());
                statusCallbackParam.setDriver_id(oaCOrder.getDriverId().toString());
                statusCallbackParam.setStatus(oaCOrder.getOrderStatus());
                statusCallbackParam.setChannel(oaCOrder.getOrderChannel());
                String str = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + oaCOrder.getDriverId());
                if (CheckUtil.strIsNotEmpty(str)) {
                    OaDVehicleGps oaDVehicleGps = JSON.parseObject(str, OaDVehicleGps.class);
                    statusCallbackParam.setDriver_lng(new BigDecimal(oaDVehicleGps.getLng()));
                    statusCallbackParam.setDriver_lat(new BigDecimal(oaDVehicleGps.getLat()));
                }
                statusCallbackParam.setIsRetry(false);

                // 同步调用滴滴同步状态,如果失败,异步重试
                Rv rv = iDidiService.statusCallback(statusCallbackParam);
                if (rv.getCode() != EErrorCode.success.getValue()) {
                    log.info("ORDER_HISTORY 订单号:[{}],调用了到达预约地点接口,调用滴滴服务返回失败,进入重试机制,请求参数:[{}],调用滴滴服务返回值:[{}] ", orderNo, statusCallbackParam, rv);
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC);
                }
                log.info("ORDER_HISTORY 订单号:[{}],调用了到达预约地点接口,返回结果:[{}],调用司机状态到滴滴请求参数:[{}],调用滴滴服务返回值:[{}] ", orderNo, result, statusCallbackParam, rv);
                return Rv.wrap(EErrorCode.success, result);
            }
        }
        throw PangException.create(EErrorCode.noData);
    }


    /**
     * 乘客到达
     * 1.添加其他费用表数据
     * 2.更改人员订单状态 dou'di
     * 3.更改
     *
     * @return
     */
    @Override
    public Rv endTakingPassengers(OrderArrivalsParam orderNo) {
        log.info("ORDER_HISTORY 订单号:[{}],到达目的地接口,请求参数:[{}]", orderNo.getOrderNo(), orderNo);
        //确认订单ID合法性
        OaDOrder oaDOrder = orderMapper.selectById(orderNo.getOrderNo());
        if (CheckUtil.objIsEmpty(oaDOrder)) {
            throw PangException.create(EErrorCode.argCheckErr);
        }
        Date date = new Date();
        OaCOrder oaCOrder = common.queryOrderMessage(orderNo.getOrderNo());
        //更改订单状态,为行程结束待支付
        if (CheckUtil.objIsEmpty(oaCOrder)) {
            log.error("未从redis中获取到订单数据!");
            throw PangException.create(EErrorCode.noData);
        }
        //验证当前订单状态是否可以继续
        if (CheckUtil.objIsEmpty(oaCOrder.getArriveTime())) {
            oaCOrder.setArriveTime(date);
        }
        oaCOrder.setOrderStatus(EOrderStatus.sendBill.getType());

        oaDOrder.setFinishTime(date);
        oaDOrder.setOrderStatus(EOrderStatus.sendBill.getType());
        if (CheckUtil.objIsNotEmpty(orderNo.getOrderStatus())) {
            oaCOrder.setOrderStatus(EOrderStatus.servicceItineraryClose.getType());
            oaDOrder.setOrderStatus(EOrderStatus.servicceItineraryClose.getType());
        }
        oaDOrder.setNormalDistanceCost(oaCOrder.getMileageFee());
        oaDOrder.setNormalTimeCost(oaCOrder.getDurationFee());
        oaDOrder.setActualEndName(orderNo.getActualEndName());
        oaDOrder.setActualTlat(orderNo.getActualTlat());
        oaDOrder.setActualTlng(orderNo.getActualTlng());
        //根据订单号与用户名更改用户订单信息
        if (common.updateOrder(oaCOrder) && this.updateById(oaDOrder)) {
            try {
                QueryWrapper<OaDUserInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.select(OaDUserInfo.DRIVER_ID, OaDUserInfo.VERSION, OaDUserInfo.ORDER_QUANTITY_COMPLETED);
                queryWrapper.eq(OaDUserInfo.DRIVER_ID, oaDOrder.getDriverId());
                OaDUserInfo one = dUserInfoService.getOne(queryWrapper);
                UpdateWrapper<OaDUserInfo> userInfoUpdateWrapper = new UpdateWrapper<>();
                userInfoUpdateWrapper.set(OaDUserInfo.ORDER_QUANTITY_COMPLETED, one.getOrderQuantityCompleted() + 1);
                userInfoUpdateWrapper.set(OaDUserInfo.VERSION, one.getVersion() + 1);
                userInfoUpdateWrapper.eq(OaDUserInfo.VERSION, one.getVersion());
                userInfoUpdateWrapper.eq(OaDUserInfo.DRIVER_ID, one.getDriverId());
                dUserInfoService.update(userInfoUpdateWrapper);
            } catch (Exception e) {
                throw DiDiException.create(EDiDiErrorCode.dUserInfoSelectFail);
            }
            redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrder.getOrderNo(), JSON.toJSONString(oaCOrder));
            Qd total = Qd.create().add("total", oaDOrder.getDrawFee());
            //到达目的地 , 请发送账单给乘客 并提醒乘客带好随身物品
            total.add("orderStatus", oaCOrder.getOrderStatus()).add("msg", MessageConstant.VOICE_END_TAKING_PASSENGERS);
            OaSysMessage oaSysMessage = new OaSysMessage();
            oaSysMessage.setMessageType(1);
            oaSysMessage.setPushCode(EBillType.COMPLETE_TRIP.getIdenifition());
            oaSysMessage.setMessageContent(MessageConstant.COMPLETE_PROMPT + oaCOrder.getPassengerPhoneSuffix() + MessageConstant.THE_TRIP);
            oaSysMessage.setDriverId(oaCOrder.getDriverId());
            oaSysMessage.setTag(oaCOrder.getTag());
            iOaSysMessageService.saveMessage(oaSysMessage);
            //-----------同步状态-----------------
            StatusCallbackParam statusCallbackParam = new StatusCallbackParam();
            try {
                statusCallbackParam.setOpen_oid(oaCOrder.getDidiOrderId());
                statusCallbackParam.setOrder_id(oaCOrder.getOrderNo());
                statusCallbackParam.setDriver_id(oaCOrder.getDriverId().toString());
                statusCallbackParam.setStatus(oaCOrder.getOrderStatus());
                statusCallbackParam.setChannel(oaCOrder.getOrderChannel());
                statusCallbackParam.setExtra(String.valueOf(oaCOrder.getTotalFee()));
                String str = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + oaCOrder.getDriverId());
                if (CheckUtil.strIsNotEmpty(str)) {
                    OaDVehicleGps oaDVehicleGps = JSON.parseObject(str, OaDVehicleGps.class);
                    statusCallbackParam.setDriver_lng(new BigDecimal(oaDVehicleGps.getLng()));
                    statusCallbackParam.setDriver_lat(new BigDecimal(oaDVehicleGps.getLat()));
                }
                statusCallbackParam.setIsRetry(false);
                // 同步状态,如果失败,异步重试
                Rv rv = iDidiService.statusCallback(statusCallbackParam);
                if (rv.getCode() != EErrorCode.success.getValue()) {
                    log.info("ORDER_HISTORY 订单号:[{}],到达目的地,同步状态失败,进入重试机制,请求参数:[{}],调用滴滴服务返回值:[{}] ", oaCOrder.getOrderNo(), statusCallbackParam, rv);
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC);
                }
                log.info("ORDER_HISTORY 订单号:[{}],到达目的地,状态同步成功 参数:[{}],返回值:[{}]", oaCOrder.getOrderNo(), statusCallbackParam, rv);
            } catch (Exception e) {
                log.info("ORDER_HISTORY 订单号:[{}],到达目的地,同步状态失败!,向滴滴同步状态实体类:[{}]", oaCOrder.getOrderNo(), statusCallbackParam);
            }

            return Rv.wrap(EErrorCode.success, total);
        } else {
            log.info("更改用户订单 OR 司机订单失败!");
            throw PangException.create(EErrorCode.unkown);
        }
    }


    /**
     * 发起收款
     *
     * @param paymentParam
     * @return
     */
    @Override
    public Rv initiatePayment(InitiatePaymentParam paymentParam) {
        log.info("ORDER_HISTORY 订单号:[{}],发起收款,请求参数:[{}]", paymentParam.getOrderNo(), paymentParam);
        //获取司机ID
        Long driverId = null;
        if (CheckUtil.objIsEmpty(paymentParam.getIsCloseOrder()) || !paymentParam.getIsCloseOrder()) {
            driverId = TokenUtil.getTokenUserId();
        }
        //从redis中获取
        OaCOrder oaCOrder = common.queryOrderMessage(paymentParam.getOrderNo());
        if (CheckUtil.objIsEmpty(oaCOrder)) {
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,请求参数:[{}],为获取到用户订单实体类,请检查订单号!", paymentParam.getOrderNo(), paymentParam);
            throw PangException.create(EErrorCode.noData);
        }
        if (CheckUtil.objIsNotEmpty(paymentParam.getIsCloseOrder()) && paymentParam.getIsCloseOrder()) {
            driverId = oaCOrder.getDriverId();
        }
        //验证当前订单状态是否可以继续
        common.canTheOrderContinue(oaCOrder.getOrderStatus());
        OaDOrder oaDOrder = orderMapper.selectById(paymentParam.getOrderNo());
        if (CheckUtil.objIsEmpty(oaDOrder)) {
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,请求参数:[{}],为获取到司机订单实体类,请检查订单号!", paymentParam.getOrderNo(), paymentParam);
            throw PangException.create(EErrorCode.noData);
        }
//        BigDecimal otherPriceTotalFee = BigDecimalUtils.value("");
//        try {
//            //获取其他总费用
//            otherPriceTotalFee = common.getOtherPriceTotalFee(oaCOrder, paymentParam, driverId);
//        } catch (Exception e) {
//            log.info("ORDER_HISTORY 订单号:[{}],发起收款,请求参数:[{}],设置私用费用失败!", paymentParam.getOrderNo(), paymentParam);
//        }
        //设置个人订单总费用
//        oaCOrder.setDrawFee(oaCOrder.getDrawFee().add(otherPriceTotalFee).setScale(2, BigDecimal.ROUND_HALF_UP));
//        oaCOrder.setTotalFee(oaCOrder.getTotalFee().add(otherPriceTotalFee).setScale(2, BigDecimal.ROUND_HALF_UP));
        if (oaCOrder.getOrderChannel().equals(EOrderChannelType.xiecheng.getType())) {
            oaDOrder.setOrderStatus(EOrderStatus.paymented.getType());
        } else {
            oaDOrder.setOrderStatus(EOrderStatus.normalOrderPendingPayment.getType());
        }
        oaCOrder.setOrderStatus(EOrderStatus.normalOrderPendingPayment.getType());
        oaCOrder.setDidiOrderStatus(EDiDiOrderStatus.normalOrderPendingPayment.getDidiType());
        //设置司机订单总费用
//        oaDOrder.setDrawFee(oaCOrder.getDrawFee());
//        oaDOrder.setTotalCost(oaCOrder.getTotalFee());
//        oaDOrder.setOrderStatus(EOrderStatus.normalOrderPendingPayment.getType());
        if (CheckUtil.objIsNotEmpty(paymentParam.getLng()) && !paymentParam.getLng().equals("0.0") &&
                CheckUtil.objIsNotEmpty(paymentParam.getLat()) && !paymentParam.getLat().equals("0.0")) {
            oaDOrder.setInitiatePaymentFlat(paymentParam.getLat());
            oaDOrder.setInitiatePaymentFlng(paymentParam.getLng());
        }
        //更改订单总金额
        if (!common.updateOrder(oaCOrder) || !this.updateById(oaDOrder)) {
            throw PangException.create(EErrorCode.noData);
        }
        // 删除缓存数据
        redisCommon.remove(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrder.getOrderNo());
        //解除司机锁定
        log.info("DRIVER_HISTORY 司机被释放了,司机当前订单号:[{}],当前订单状态:[{}],司机ID:[{}]", oaCOrder.getOrderNo(), oaCOrder.getOrderStatus(), driverId);
        common.destinationEmancipationDriver(false, oaCOrder.getDriverId(), oaCOrder.getOrderNo());
        //-----------设置用户冻结金额-----------------
        OaDFreeze oaDFreeze = new OaDFreeze();
        try {
            oaDFreeze.setOrderNumber(oaCOrder.getOrderNo());
            oaDFreeze.setFreezeAmount(oaCOrder.getDrawFee());
            oaDFreeze.setDriverId(oaCOrder.getDriverId());
            oaDFreeze.setTag(oaCOrder.getTag());
            oaDFreeze.setBillTypeDesc("1");
            oaDFreeze.setTag(TokenUtil.getTag());
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,保存用户冻结金额!,冻结金额实体类:[{}]", paymentParam.getOrderNo(), oaDFreeze);
            oaDFreezeService.saveFreezeBalance(oaDFreeze);
        } catch (Exception e) {
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,设置用户冻结金额失败!,冻结金额实体类:[{}]", paymentParam.getOrderNo(), oaDFreeze);
        }
        //-----------同步状态-----------------
        StatusCallbackParam statusCallbackParam = new StatusCallbackParam();
        try {
            statusCallbackParam.setOpen_oid(oaCOrder.getDidiOrderId());
            statusCallbackParam.setOrder_id(oaCOrder.getOrderNo());
            statusCallbackParam.setDriver_id(oaCOrder.getDriverId().toString());
            statusCallbackParam.setStatus(oaCOrder.getOrderStatus());
            statusCallbackParam.setChannel(oaCOrder.getOrderChannel());
            statusCallbackParam.setExtra(String.valueOf(oaCOrder.getTotalFee()));
            String str = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + oaCOrder.getDriverId());
            if (CheckUtil.strIsNotEmpty(str)) {
                OaDVehicleGps oaDVehicleGps = JSON.parseObject(str, OaDVehicleGps.class);
                statusCallbackParam.setDriver_lng(new BigDecimal(oaDVehicleGps.getLng()));
                statusCallbackParam.setDriver_lat(new BigDecimal(oaDVehicleGps.getLat()));
            }
            statusCallbackParam.setIsRetry(false);
            long preTime = oaCOrder.getAppointment().getTime() - System.currentTimeMillis();
            if (preTime > 0 && oaCOrder.getOrderChannel() == EOrderChannelType.xiecheng.getType()) {
                log.error("ORDER_STATUS 订单号:[{}]，超前送达，时间:[{}]", paymentParam.getOrderNo(), preTime);
                //携程要求在用车时间/航班预计落地时间后再推送订单完成
                if (preTime < 10 * 60 * 1000) {
                    //提前时间小于10分钟则延迟10分钟后同步getNewOrderList
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, 14);
                } else if (preTime < 20 * 60 * 1000) {
                    //提前时间小于20分钟则延迟20分钟后同步
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, 15);
                } else if (preTime < 30 * 60 * 1000) {
                    //提前时间小于30分钟则延迟30分钟后同步
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, 16);
                } else if (preTime < 60 * 60 * 1000) {
                    //提前时间小于60分钟则延迟60分钟后同步
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, 17);
                } else if (preTime < 120 * 60 * 1000) {
                    //提前时间小于120分钟则延迟120分钟后同步
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC, 18);
                }
            } else if(oaCOrder.getOrderChannel() == EOrderChannelType.tongcheng.getType() ||
                    oaCOrder.getOrderChannel() == EOrderChannelType.xiecheng.getType()){
                // 同步调用滴滴同步状态,如果失败,异步重试
                Rv rv = iDidiService.statusCallback(statusCallbackParam);
                if (rv.getCode() != EErrorCode.success.getValue()) {
                    log.info("ORDER_HISTORY 订单号:[{}],发起收款,调用滴滴服务返回失败,进入重试机制,请求参数:[{}],调用滴滴服务返回值:[{}] ", paymentParam.getOrderNo(), statusCallbackParam, rv);
                    producer.sendMsg(statusCallbackParam, MqConstant.STATUS_CALL_BACK_SYNC);
                }
                log.info("ORDER_HISTORY 订单号:[{}],发起收款,调用滴滴状态同步 参数:[{}],返回值:[{}]", paymentParam.getOrderNo(), statusCallbackParam, rv);
            } else if (oaCOrder.getOrderChannel() == EOrderChannelType.ordinary.getType()) {
                oaDOrder.setOrderStatus(EOrderStatus.paymented.getType());
                this.updateById(oaDOrder);
                UpdateWrapper updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq(OaCOrderPersonal.ORDER_NO, oaCOrder.getOrderNo());
                updateWrapper.set(OaCOrderPersonal.ORDER_STATUS, EOrderStatus.paymented.getType());
                oaCOrderPersonalMapper.update(null, updateWrapper);
            }
        } catch (Exception e) {
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,向滴滴同步状态失败!,向滴滴同步状态实体类:[{}]", paymentParam.getOrderNo(), statusCallbackParam);
        }

        saveOaDBill(driverId, oaDOrder.getOrderNo(), oaCOrder.getDrawFee());
        Qd msg = Qd.create().add("msg", MessageConstant.VOICE_INITIATE_BILL + oaCOrder.getDrawFee() + MessageConstant.MONEY_NAME + MessageConstant.VOICE_INITIATE_BILL_WALLET);
        log.info("ORDER_HISTORY 订单号:[{}],发起收款,返回值内容:[{}]", paymentParam.getOrderNo(), msg);
        return Rv.wrap(EErrorCode.success, msg);
    }

    /**
     * 获取订单总费用
     *
     * @param orderNo 订单Id
     * @return
     */
    @Override
    public Rv getInitiatePaymentInfo(String orderNo, String appCode) {
//        if (StringUtils.isBlank(appCode)) {
//            throw PangException.create(EErrorCode.noData);
//        }
//        String[] systemMessage = appCode.split(":");
//        String type = systemMessage[0];
//        Integer version = Integer.parseInt(systemMessage[1]);
//        Boolean validation = false;
//        // 旧版本
//        if (type.equals(ESystemType.a.getValue()) && version <= 104) {
//            validation = true;
//        }
//        if (type.equals(ESystemType.b.getValue()) && version <= 100) {
//            validation = true;
//        }
        //首先从redis中获取订单信息,如果未获取到从mysql中获取
        OaCOrderPersonal oaCOrder = null;
        String str = redisCommon.getStr(RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo);
        if (CheckUtil.strIsNotEmpty(str)) {
            oaCOrder = JSON.parseObject(str, OaCOrderPersonal.class);
        } else {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
            List<OaCOrderPersonal> orderList = oaCOrderPersonalMapper.selectList(queryWrapper);
            if (CheckUtil.collectionIsEmpty(orderList)) {
                log.info("未获取到订单信息!");
                throw PangException.create(EErrorCode.infoIsNull);
            }
            //因为orderList中的订单class与OaCOrderPersonal的class类型不一致,所以出此下册
            oaCOrder = JSON.parseObject(JSON.toJSONString(orderList.get(0)), OaCOrderPersonal.class);
        }
        //最终判断订单信息是否为空
        if (CheckUtil.objIsEmpty(oaCOrder)) {
            log.info("未获取到订单信息!");
            throw PangException.create(EErrorCode.infoIsNull);
        }
        // 获取平台抽成比
        //OaSysBillRules oaSysBillRules = iOaDOrderCorrelationService.getDrawRatio(oaCOrder.getRulesId());
        Qd result = Qd.create();
        String carType = EvehicleType.findById(oaCOrder.getVehicleType()).getValue();
        // 通过版本号判断
        result.add("totalFee", oaCOrder.getDrawFee())//抽成过后的总费用
                .add("carType", carType)
                .add("orderNo", orderNo);
        return Rv.wrap(EErrorCode.success, result);
    }

    /**
     * 第一期功能版本
     *
     * @param oaCOrder
     * @param oaSysBillRules
     * @param orderNo
     * @return
     */
    public Qd getFirstStageVersion(OaCOrderPersonal oaCOrder, OaSysBillRules oaSysBillRules, String orderNo) {
        Qd result = Qd.create();
        BigDecimal totalFee = oaCOrder.getDrawFee();
        if (CheckUtil.objIsEmpty(totalFee)) {
            totalFee = new BigDecimal(0);
        }
        BigDecimal zero = new BigDecimal(0);
        List<OrderBillDetailResults> resultsList = new ArrayList<>();
        if (CheckUtil.objIsNotEmpty(oaCOrder.getStartFee(), oaCOrder.getRulesId()) && oaCOrder.getStartFee().compareTo(zero) == 1) {
            OrderBillDetailResults startFeeResults = new OrderBillDetailResults();
            if (CheckUtil.objIsNotEmpty(oaSysBillRules)) {
                startFeeResults.setName(MessageConstant.START + "(" + oaSysBillRules.getStartMileage() + MessageConstant.KILOMETRE + " " + oaSysBillRules.getStartTime() + MessageConstant.MINUTES + ")");
                startFeeResults.setMoney(iOaDOrderCorrelationService.draw(oaCOrder.getStartFee(), oaSysBillRules.getDrawRatio()) + MessageConstant.MONEY_NAME);
                resultsList.add(startFeeResults);
            }
        }
        if (CheckUtil.objIsNotEmpty(oaCOrder.getMileageFee(), oaCOrder.getMilageDistance()) && oaCOrder.getMileageFee().compareTo(zero) == 1) {
            OrderBillDetailResults mileageFeeResults = new OrderBillDetailResults();
            mileageFeeResults.setName(MessageConstant.MILEAGE + "(" + oaCOrder.getMilageDistance() + MessageConstant.KILOMETRE + ")");
            mileageFeeResults.setMoney(iOaDOrderCorrelationService.draw(oaCOrder.getMileageFee(), oaSysBillRules.getDrawRatio()) + MessageConstant.MONEY_NAME);
            resultsList.add(mileageFeeResults);
        }
        if (CheckUtil.objIsNotEmpty(oaCOrder.getDurationFee(), oaCOrder.getDurationTime()) && oaCOrder.getDurationFee().compareTo(zero) == 1) {
            OrderBillDetailResults durationFeeResults = new OrderBillDetailResults();
            durationFeeResults.setName(MessageConstant.DURATION + "(" + oaCOrder.getDurationTime() + MessageConstant.MINUTES + ")");
            durationFeeResults.setMoney(iOaDOrderCorrelationService.draw(oaCOrder.getDurationFee(), oaSysBillRules.getDrawRatio()) + MessageConstant.MONEY_NAME);
            resultsList.add(durationFeeResults);
        }
        if (CheckUtil.objIsNotEmpty(oaCOrder.getDistanceFee(), oaCOrder.getEmptyDistance()) && oaCOrder.getDistanceFee().compareTo(zero) == 1) {
            OrderBillDetailResults distanceFeeResults = new OrderBillDetailResults();
            distanceFeeResults.setName(MessageConstant.DISTANT + "(" + oaCOrder.getEmptyDistance() + MessageConstant.KILOMETRE + ")");
            distanceFeeResults.setMoney(iOaDOrderCorrelationService.draw(oaCOrder.getDistanceFee(), oaSysBillRules.getDrawRatio()) + MessageConstant.MONEY_NAME);
            resultsList.add(distanceFeeResults);
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(OaOrderOtherPrice.ORDER_NO, orderNo);
        List<OaOrderOtherPrice> otherPriceList = oaOrderOtherPriceMapper.selectList(queryWrapper);
        if (!otherPriceList.isEmpty()) {
            for (OaOrderOtherPrice o : otherPriceList) {
                if (o.getCostAmount().compareTo(zero) == 1) {
                    OrderBillDetailResults otherPriceResults = new OrderBillDetailResults();
                    otherPriceResults.setName(EOrderOtherPrice.findById(o.getCostType()).getValue());
                    otherPriceResults.setMoney(o.getCostAmount() + MessageConstant.MONEY_NAME);
                    resultsList.add(otherPriceResults);
                }
            }
        }
        String carType = "";
        if (CheckUtil.objIsNotEmpty(oaCOrder.getVehicleType())) {
            carType = EvehicleType.findById(oaCOrder.getVehicleType()).getValue();
        }
        result = Qd.create()
                .add("totalFee", totalFee)
                .add("carType", carType)
                .add("resultsList", resultsList);
        return result;
    }

    /**
     * 获取司机订单总金额
     *
     * @return
     */
    @Override
    public Rv getDriverOrderStatus() {
        NettyDriverOrderInfo driverOrderInfo = new NettyDriverOrderInfo();
        driverOrderInfo.setStartRecord(startRecord);
        //大于0代表有未完结的订单
//        OaCOrder order = common.getOrderById(TokenUtil.getTokenUserId() + "", 0);
        //获取司机信息
        Long driverId = TokenUtil.getTokenUserId();
        Map<String, Object> stringObjectMap = oaDUserMapper.queryDriverInfoByDriverId(driverId);
        OaCOrder order = null;
        //判断是否开始接单中
        if (stringObjectMap.containsKey("currentOrderNo")) {
            String orderNo = stringObjectMap.get("currentOrderNo").toString();
            if (CheckUtil.strIsNotEmpty(orderNo)) {
                String orderJson = redisCommon.getStr(RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo);
                if (CheckUtil.objIsEmpty(orderJson)) {
                    order = common.selectOn(orderNo);
                } else {
                    order = JSON.parseObject(orderJson, OaCOrder.class);
                }
                //如果为空不需要进行检验
                if (CheckUtil.objIsNotEmpty(order)) {
                    //因为有几率存在抢单失败,但是未释放司机的问题,所以在此做一个释放.....实属时间紧张,无奈啊
                    //判断当前订单状态释放,因为释放司机
                    EOrderStatus orderStatus = EOrderStatus.findById(order.getOrderStatus());
                    //判断当前状态是否应该释放司机
                    boolean freedDriver = EOrderStatus.isFreedDriver(orderStatus);
                    if (freedDriver) {
                        order = null;
                    }
                }
            }
        }
        if (CheckUtil.objIsNotEmpty(order)) {
            Integer orderStatus = order.getOrderStatus();
            driverOrderInfo = common.getOrderInfo(order, driverOrderInfo);
            driverOrderInfo.setArrivePrompt("");
            driverOrderInfo.setReciprocalTime(0);
            if (CheckUtil.objIsNotEmpty(order.getArriveMeetPassengerTime())) {
                Long reciprocalTime = System.currentTimeMillis() - order.getArriveMeetPassengerTime().getTime();
                driverOrderInfo.setReciprocalTime(reciprocalTime.intValue() / 1000);
            }
            String phone = order.getPassengerPhone();
            driverOrderInfo.setPhone(phone);
            driverOrderInfo.setServiceId(Long.valueOf(common.getServiceId()));
            if (CheckUtil.objIsNotEmpty(order.getDriverId())) {
                driverOrderInfo.setTid(Long.valueOf(common.getTid(String.valueOf(order.getDriverId()))));
            }
            driverOrderInfo.setIsEvaluation(common.isEvaluation(order.getDriverId(), ONE.getType(), order.getOrderNo()));
            driverOrderInfo.setTailNumber(MessageConstant.TAILNUMBER + order.getPassengerPhoneSuffix());
            driverOrderInfo.setCallVehType(MessageConstant.ORDER_TYPE_ONE);
            BigDecimal showFee = new BigDecimal(ZERO.getTypeName());
//            if (CheckUtil.objIsNotEmpty(order.getRulesId())) {
//                OaSysBillRules billRules = billRulesCommon.startFee(String.valueOf(order.getRulesId()), TokenUtil.getTag());
//                showFee = common.getTotalFee(order.getTotalFee(), order.getBaseFee(), EUserTypeNum.d.getValue(), billRules.getDrawRatio());
//            }
            driverOrderInfo.setTotalFee(order.getDrawFee() + "");
            String vehJson = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + order.getDriverId());
            OaDVehicleGps oaDVehicleGps = JSON.parseObject(vehJson, OaDVehicleGps.class);
            if (CheckUtil.objIsNotEmpty(oaDVehicleGps)) {
                String gouldDuration = null;
                String gouldDistance = null;
                String gouldIntDistance = null;
                if (orderStatus.equals(EOrderStatus.reservationLocation.getType())) {
                    if (CheckUtil.objIsNotEmpty(oaDVehicleGps.getLng()) && CheckUtil.objIsNotEmpty(oaDVehicleGps.getLat()) && GpsUtil.checkItude(order.getStartLng(), order.getStartLat())) {
                        Map<String, String> strategy = amapService.getDistanceAndDuration(oaDVehicleGps.getLng() + "," + oaDVehicleGps.getLat(), order.getStartLng() + "," + order.getStartLat());
                        gouldDuration = strategy.get(EGould.gouldDuration.getValue());
                        gouldDistance = strategy.get(EGould.gouldDistance.getValue());
                        gouldIntDistance = strategy.get(EGould.gouldIntDuration.getValue());
                    }
                    if (CheckUtil.strIsNotEmpty(gouldIntDistance)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                        Date appointmentTime = order.getAppointment();
                        if (order.getOrderType() == ECallVehType.expressTrain.getType() || appointmentTime == null) {
                            BigDecimal big = new BigDecimal(gouldIntDistance).setScale(0, BigDecimal.ROUND_UP);
                            Calendar nowTime = Calendar.getInstance();
                            nowTime.add(Calendar.MINUTE, big.intValue());
                            driverOrderInfo.setArrivePrompt(MessageConstant.PLEASE_PROMPT + sdf.format(nowTime.getTime()) + MessageConstant.ARRIVE_PROMPT);
                        } else {
                            driverOrderInfo.setArrivePrompt(MessageConstant.PLEASE_PROMPT + sdf.format(appointmentTime.getTime()) + MessageConstant.ARRIVE_PROMPT);
                        }
                    }
                } else if (orderStatus.equals(EOrderStatus.duringTrip.getType()) || orderStatus.equals(EOrderStatus.privateItinerary.getType())) {
                    if (CheckUtil.objIsNotEmpty(oaDVehicleGps.getLng()) && CheckUtil.objIsNotEmpty(oaDVehicleGps.getLat()) && GpsUtil.checkItude(order.getEndLng(), order.getEndLat())) {
                        Map<String, String> strategy = amapService.getDistanceAndDuration(oaDVehicleGps.getLng() + "," + oaDVehicleGps.getLat(), order.getEndLng() + "," + order.getEndLat());
                        gouldDuration = strategy.get(EGould.gouldDuration.getValue());
                        gouldDistance = strategy.get(EGould.gouldDistance.getValue());
                    }
                }
                //里程与里程时长
                if (CheckUtil.strIsNotEmpty(gouldDuration) && CheckUtil.strIsNotEmpty(gouldDistance)) {
                    driverOrderInfo.setDistance(order.getMilageDistance() + " " + order.getDurationTime());
                    driverOrderInfo.setDistanceTime("");
                }
            }
            List<Qd> gpsList = gpsCommon.getHistroyGpsList(order.getOrderNo());
            driverOrderInfo.setGpsList(gpsList);
        }
        // 查询司机剩余取消次数
        QueryWrapper<OaSysGlobalConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(OaSysGlobalConfig.CANCEL_NUMBER);
        List<OaSysGlobalConfig> oaSysGlobalConfigs = oaSysGlobalConfigMapper.selectList(queryWrapper);
        OaSysGlobalConfig oaSysGlobalConfig = null;
        if (CheckUtil.collectionIsNotEmpty(oaSysGlobalConfigs)) {
            oaSysGlobalConfig = oaSysGlobalConfigs.get(0);
        }
        Integer cancelNumber = oaSysGlobalConfig.getCancelNumber();
        if (cancelNumber == null || cancelNumber < 0) {
            cancelNumber = 0;
        }
        QueryWrapper<DriverCancelOrderRecord> cancelWrapper = new QueryWrapper<>();
        cancelWrapper.select(DriverCancelOrderRecord.RECORD_ID);
        cancelWrapper.eq(DriverCancelOrderRecord.DRIVER_ID, driverId);
        List<DriverCancelOrderRecord> driverCancelOrderRecords = driverCancelOrderRecordMapper.selectList(cancelWrapper);
        cancelNumber = cancelNumber - driverCancelOrderRecords.size();
        if (cancelNumber < 0) {
            cancelNumber = 0;
        }
        driverOrderInfo.setCancelCount(cancelNumber);
        driverOrderInfo.setDistance("时间 暂无");
        driverOrderInfo.setDistanceTime("");
        return Rv.wrap(EErrorCode.success, driverOrderInfo);
    }


    /**
     * 司机端根据订单号获取订单支付详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getDriverOrderDetails(String orderNo) {
        OaCOrder oaCOrder = common.selectOn(orderNo);
        List<Qd> feeList = new ArrayList<>();
        //设置基础费
        BigDecimal baseFee = oaCOrder.getBaseFee();
        boolean cancel = EOrderStatus.isCancel(EOrderStatus.findById(oaCOrder.getOrderStatus()));
        if (cancel) {
            if (!CheckUtil.objIsEmpty(baseFee) && baseFee.doubleValue() > 0) {
                Qd fee = Qd.create();
                fee.add("type", ECostDetailsName.baseFee.getName());
                fee.add("value", String.format("%s%s", baseFee.doubleValue(), MessageConstant.MONEY_NAME));
                feeList.add(fee);
            }
            //设置里程费
            BigDecimal mileageFee = oaCOrder.getMileageFee();
            if (!CheckUtil.objIsEmpty(mileageFee) && mileageFee.doubleValue() > 0) {
                Qd fee = Qd.create();
                fee.add("type", String.format(ECostDetailsName.totalMileageFee.getName(), oaCOrder.getMilageDistance()));
                fee.add("value", String.format("%s%s", mileageFee.doubleValue(), MessageConstant.MONEY_NAME));
                feeList.add(fee);
            }
            //设置时长费
            BigDecimal durationFee = oaCOrder.getDurationFee();
            if (!CheckUtil.objIsEmpty(durationFee) && durationFee.doubleValue() > 0) {
                Qd fee = Qd.create();
                fee.add("type", String.format(ECostDetailsName.totalTimeFee.getName(), oaCOrder.getDurationTime()));
                fee.add("value", String.format("%s%s", durationFee.doubleValue(), MessageConstant.MONEY_NAME));
                feeList.add(fee);
            }
            //设置远途费
            BigDecimal distanceFee = oaCOrder.getDistanceFee();
            if (!CheckUtil.objIsEmpty(distanceFee) && distanceFee.doubleValue() > 0) {
                Qd fee = Qd.create();
                fee.add("type", ECostDetailsName.longDistanceFee.getName());
                fee.add("value", String.format("%s%s", distanceFee.doubleValue(), MessageConstant.MONEY_NAME));
                feeList.add(fee);
            }
            List<OaOrderOtherPrice> list = otherPriceMapper.selectList(Qw.create().eq(
                    OaOrderOtherPrice.ORDER_NO, oaCOrder.getOrderNo()
            ));
            for (OaOrderOtherPrice price : list) {
                BigDecimal costAmount = price.getCostAmount();
                if (!CheckUtil.objIsEmpty(costAmount) && costAmount.doubleValue() > 0) {
                    Qd fee = Qd.create();
                    fee.add("value", String.format("%s%s", costAmount, MessageConstant.MONEY_NAME));
                    fee.add("type", EOrderOtherPrice.findById(price.getCostType()));
                    feeList.add(fee);
                }
            }
        }
        OaDOrder oaDOrder = orderMapper.selectById(oaCOrder.getOrderNo());
        Qd result = Qd.create().add("totalFee", oaCOrder.getTotalFee());
        result.add("feeList", feeList);
        if (!CheckUtil.objIsEmpty(oaDOrder)) {
            result.add("orderType", OrderUtil.orderType(oaDOrder.getIsCarpool()));
        }
        return Rv.wrap(EErrorCode.success, result);
    }


    /**
     * 获取历史轨迹
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getHistoryGps(String orderNo) {
        Map<String, Object> map = orderMapper.queryOrderInfo(orderNo,null);
        int orderStatus = (Integer) map.get("orderStatus");
        map.put("totalCost", map.get("totalCost").toString() + "元");
        map.put("titleText", "");
        if (
                orderStatus == EOrderStatus.normalOrderPendingPayment.getType() ||
                        orderStatus == EOrderStatus.paymented.getType()) {
            map.put("orderStatus", 2);
            if (CheckUtil.objIsNotEmpty(map.get("startAddressName"))) {
                map.put("actualStartName", map.get("startAddressName"));
                map.put("actualFlat", map.get("startLat"));
                map.put("actualFlng", map.get("startLng"));
            }
            if (CheckUtil.objIsNotEmpty(map.get("endAddressName"))) {
                map.put("actualEndName", map.get("endAddressName"));
                map.put("actualTlat", map.get("endLat"));
                map.put("actualTlng", map.get("endLng"));
            }
        } else if (orderStatus == OrderStatusConstant.WAIT_APPLY_AMOUNT) {
            map.put("orderStatus", 3);
            if (CheckUtil.objIsNotEmpty(map.get("startAddressName"))) {
                map.put("actualStartName", map.get("startAddressName"));
                map.put("actualFlat", map.get("startLat"));
                map.put("actualFlng", map.get("startLng"));
            }
            if (CheckUtil.objIsNotEmpty(map.get("endAddressName"))) {
                map.put("actualEndName", map.get("endAddressName"));
                map.put("actualTlat", map.get("endLat"));
                map.put("actualTlng", map.get("endLng"));
            }
        } else if (
                orderStatus == EOrderStatus.reassigned.getType() ||
                        orderStatus == EOrderStatus.serviceClose.getType() ||
                        orderStatus == EOrderStatus.driverCancelOrder.getType() ||
                        orderStatus == EOrderStatus.cancelPendingPayment.getType() ||
                        orderStatus == EOrderStatus.cancelOrdersFeesPaid.getType() ||
                        orderStatus == EOrderStatus.cancelOrderNoNeedPayment.getType() ||
                        orderStatus == EOrderStatus.abnormalEndOrder.getType()
        ) {
            map.put("orderStatus", 1);
        } else {
            map.put("orderStatus", 0);

            String startPoint = map.get("actualFlng").toString() + "," + map.get("actualFlat").toString();
            String endPoint = map.get("actualTlng").toString() + "," + map.get("actualTlat").toString();

            Map<String, String> amap = iAmapService.getDistanceAndDuration(startPoint, endPoint);

            String distance = amap.get(EGould.gouldDistance.getValue());
            String duration = amap.get(EGould.gouldDuration.getValue());
            map.put("titleText", "此次行程预计" + distance + "，大约需要" + duration);
        }

        String driverPhone = map.get("driverPhone").toString();
        driverPhone = driverPhone.substring(driverPhone.length() - 4);
        map.put("driverPhone", MessageConstant.TAILNUMBER + driverPhone);

        // 获取客服电话
        QueryWrapper<OaSysGlobalConfig> oaSysGlobalConfigQueryWrapper = new QueryWrapper<>();
        oaSysGlobalConfigQueryWrapper.select(OaSysGlobalConfig.SERVICE_PHONE);
        List<OaSysGlobalConfig> oaSysGlobalConfigs = null;
        try {
            oaSysGlobalConfigs = oaSysGlobalConfigMapper.selectList(oaSysGlobalConfigQueryWrapper);
        } catch (Exception e) {
            map.put("servicePhone", "");
        }
        if (CheckUtil.collectionIsNotEmpty(oaSysGlobalConfigs)) {
            try {
                map.put("servicePhone", oaSysGlobalConfigs.get(0).getServicePhone());
            } catch (NullPointerException e) {
                map.put("servicePhone", "");
            }
        } else {
            map.put("servicePhone", "");
        }

        if (CheckUtil.objIsEmpty(map.get(OaDUser.AVATAR_FILE_ID))) {
            map.put("avatarFile", "");
        } else {
            Rv rv = feignMessageSendService.getFileUrl((Long) map.get(OaDUser.AVATAR_FILE_ID));
            if (rv.getCode() == GET_IMAGE_FILED) {
                map.put("avatarFile", "");
            } else {
                String fileUrl = ((Map<String, String>) (rv.getData())).get("fileUrl");
                map.put("avatarFile", fileUrl);
            }
        }
        // 获取行程轨迹
        /*Rv trajectoryObject = feignTrajectoryService.getOrderTrajectory(orderNo);

        List<Map<String, String>> mapList = new ArrayList<>();
        List<OaDVehicleGpsHistory> oaDVehicleGpsHistories = new ArrayList<>();

        if (trajectoryObject.getCode() == 0) {
            oaDVehicleGpsHistories = JSON.parseArray(JSON.toJSONString(trajectoryObject.getData()), OaDVehicleGpsHistory.class);
        }

        if (CheckUtil.collectionIsNotEmpty(oaDVehicleGpsHistories)) {
            for (OaDVehicleGpsHistory oaDVehicleGpsHistory : oaDVehicleGpsHistories) {
                Map<String, String> gps = new HashMap<>(2);
                gps.put("lat", oaDVehicleGpsHistory.getLat());
                gps.put("lng", oaDVehicleGpsHistory.getLng());
                mapList.add(gps);
            }
        }*/
        List<Qd> histroyGpsList = gpsCommon.getHistroyGpsList(orderNo);
        map.put("gpsList", histroyGpsList);
        return Rv.wrap(EErrorCode.success, map);
    }

    /**
     * 更新用户订单信息
     *
     * @param oaCOrderPersonal
     * @return
     */
    @Override
    public Boolean updateUserOrderInfo(OaCOrderPersonal oaCOrderPersonal) {
        oaCOrderPersonal.setUserId("0");
        redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrderPersonal.getOrderNo(), JSON.toJSONString(oaCOrderPersonal));
        return personalDiDiService.updateById(oaCOrderPersonal);
    }

    @Override
    public List<OaOrderOtherPrice> queryOrderOtherPrice(String orderNo) {
        return common.queryOtherPrice(orderNo);
    }

    @Override
    public boolean updateOrderOtherPrice(List<OaOrderOtherPrice> otherPrices) {
        return common.updateOrderOtherPrice(otherPrices);
    }

    @Override
    public void saveOaDBill(Long driverId, String orderId, BigDecimal drawFee) {
        // 账单派发
        OaDBill oaDBill = new OaDBill();
        try {
            log.info("--------------------------------------------------------------------------------");
            log.info("此账单派给司机：{}", driverId);
            log.info("--------------------------------------------------------------------------------");
            oaDBill.setDriverId(driverId);
            oaDBill.setOrderNumber(orderId);
            oaDBill.setBillAmount(drawFee);
            int compare = drawFee.compareTo(BigDecimal.ZERO);
            if (compare >= 0) {
                oaDBill.setBillType(BillConstant.INCOME);
                oaDBill.setBillTypeDesc(BillConstant.BILL_TYPE_DESC);
            } else {
                oaDBill.setBillType(BillConstant.EXPAND);
                oaDBill.setBillTypeDesc(BillConstant.BILL_TYPE_PUNISH);
            }
            oaDBill.setLogonTag(BillConstant.LogonTag);
            oaDBill.setTag(TokenUtil.getTag());
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,调用finance服务保存账单,并且保存消息,当前账单内容:[{}]", orderId, oaDBill);
            oaDFreezeService.saveDriverBill(oaDBill);
        } catch (Exception e) {
            log.info("ORDER_HISTORY 订单号:[{}],发起收款,账单发送失败,并且保存消息,当前账单内容:[{}]", orderId, oaDBill);
        }
    }

    /**
     * 上传点位数据
     *
     * @param oaDOrder
     * @return
     */
    @Override
    public boolean uploadTrackFromMongo(OaDOrder oaDOrder) {
        /*String orderNo = oaDOrder.getOrderNo();
        //GouldMapUtil
        //出发时间
        Date departureTime = oaDOrder.getDepartureTime();
        //计价时间
        Date beginChargeTime = oaDOrder.getBeginChargeTime();
        //结束时间
        Date finishTime = oaDOrder.getFinishTime();
        Query query=new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo).and("operateTime").gte(departureTime).lte(beginChargeTime));
        //从司机出发到开始计价的轨迹
        List<TrackInfo> trackInfo1 = mongoTemplate.find(query, TrackInfo.class, "trackInfo");
        query=new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo).and("operateTime").gte(beginChargeTime).lte(finishTime));
        //开始计价到订单结束
        List<TrackInfo> trackInfo2 = mongoTemplate.find(query, TrackInfo.class, "trackInfo");
        if (trackInfo1.size()<1 || trackInfo2.size()<1){
            log.error("未查询到轨迹数据，订单："+orderNo);
            return false;
        }
        *//*QueryWrapper<OaDUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq(OaDUser.DRIVER_ID,oaDOrder.getDriverId());
        OaDUser oaDUser = oaDUserMapper.selectOne(queryWrapper);*//*
        QueryWrapper<OaDUserInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq(OaDUserInfo.DRIVER_ID,oaDOrder.getDriverId());
        OaDUserInfo oaDUserInfo=oaDUserInfoMapper.selectOne(queryWrapper);
        Long terminalId = oaDUserInfo.getTid();
        //创建轨迹id
        GouldLYResult result = GouldMapUtils.registTrace(serviceId, terminalId.toString(), orderNo + "：接乘客轨迹");
        GouldLYResult result2 = GouldMapUtils.registTrace(serviceId, terminalId.toString(), orderNo + "：开始计价轨迹");
        if ("10000".equals(result.getErrcode()) && "10000".equals(result2.getErrcode())){
            for (int i = 0; i < trackInfo1.size(); i+=100) {
                List<TrackInfo> uploadData = new ArrayList<>();
                if (trackInfo1.size()-i<100){
                    uploadData=trackInfo1.subList(i,trackInfo1.size());
                }else {
                    uploadData = trackInfo1.subList(i, i + 100);
                }
                //上传轨迹
                GouldMapUtils.uploadTrackNew(Long.parseLong(serviceId),terminalId,result.getData().getTrid(),
                        JSON.toJSONString(uploadData));
            }
            for (int i = 0; i < trackInfo2.size(); i+=100) {
                List<TrackInfo> uploadData = new ArrayList<>();
                if (trackInfo2.size()-i<100){
                    uploadData=trackInfo2.subList(i,trackInfo2.size());
                }else {
                    uploadData = trackInfo2.subList(i, i + 100);
                }
                //上传轨迹
                GouldMapUtils.uploadTrackNew(Long.parseLong(serviceId),terminalId,result.getData().getTrid(),
                        JSON.toJSONString(uploadData));
            }
            String trackId=result.getData().getTrid()+","+result2.getData().getTrid();
            oaDOrder.setTrackId(trackId);
            orderMapper.updateById(oaDOrder);
        }else {
            log.error("创建轨迹失败："+orderNo);
            return false;
        }
*/
        return true;
    }


}
